<?php

if (!defined('APP_RUN'))
	exit();

function autoLoad($_name) {
	static $_loaded_helpers = array();
	static $_loaded_models = array();

	if (preg_match("/^(m|M)(o|O)(d|D)(e|E)(l|L)_.+$/", $_name)) {
		if (in_array(strtolower($_name), $_loaded_models)) {
			return;
		}
		if (file_exists('system/models/' . strtolower(substr($_name, 6)) . '.php')) {
			include_once('system/models/' . strtolower(substr($_name, 6)) . '.php');
			$_loaded_models[] = strtolower($_name);
		}
	} else if (preg_match("/^(h|H)(e|E)(l|L)(p|P)(e|E)(r|R)_.+$/", $_name)) {
		if (in_array(strtolower($_name), $_loaded_helpers)) {
			return;
		}
		if (file_exists('system/helpers/' . strtolower(substr($_name, 7)) . '.php')) {
			include_once('system/helpers/' . strtolower(substr($_name, 7)) . '.php');
			$_loaded_helpers[] = strtolower($_name);
		}
	}
}

class ARCHEZ {
	const ACCESS_USER = 1;
	const ACCESS_MODERATOR = 2;
	const ACCESS_ADMINISTRATOR = 3;

	public $db = null;
	public $config = null;
	public $ots = null;
	private static $oInstance = false;

	public static function getInstance() {
		if (self::$oInstance == false) {
			self::$oInstance = new ARCHEZ();
		}
		return self::$oInstance;
	}

	function showMsg($msg, $type) {
		echo '<table cellpadding="8" cellspacing="1" width="100%"><tr class="head"><td><b>' . ucfirst($type) . '</b></td></tr><tr><td>' . $msg . '</td></tr></table>';
	}

	function checkNickname($nick) {
		$pattern = strspn($nick, 'qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM0123456789 ');
		if ($pattern != strlen($nick)) {
			return false;
		} else {
			$allowed = "/[a-zA-Z]/";
			return (preg_match($allowed, $nick)) ? true : false;
		}
	}

	function checkAccountName($name) {
		$pattern = strspn($name, 'qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM0123456789');
		if ($pattern != strlen($name)) {
			return false;
		} else {
			$allowed = "/[a-zA-Z0-9]/";
			return (preg_match($allowed, $name)) ? true : false;
		}
	}

	function checkCharacterName($name) {
		if (strlen($name) > 25)
			return false;
		$not_allowed_words = $this->config['website']['not_allowed']['words'];
		$not_allowed_strings = $this->config['website']['not_allowed']['strings'];
		$tname = explode(' ', $name);
		foreach ($tname as $word) {
			foreach ($not_allowed_words as $not_allowed_word) {
				if (strtolower($word) == $not_allowed_word) {
					return false;
				}
			}
		}
		foreach ($not_allowed_strings as $not_allowed_string) {
			if (preg_match('/^.*' . $not_allowed_string . '.*$/D', $name)) {
				return false;
			}
		}
		return $this->checkBaseName($name);
	}

	function checkBaseName($name) {
		$allowed = "/^[A-Z]{1}[a-z]{1,}(\s*(([A-Z]{1}[a-z]{1,})|([a-z]{2,})))*$/"; // can use only A-Z and spaces!
		return (preg_match($allowed, $name)) ? true : false;
	}

	function checkGuildNick($name) {
		if (strlen($name) > 25)
			return false;
		$allowed = "/^[A-Za-z0-9 ]+$/";
		return (preg_match($allowed, $name)) ? true : false;
	}

	function checkGuildName($name) {
		return $this->checkCharacterName($name);
	}

	function checkPassword($password) {
		$pattern = strspn($password, 'qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM0123456789');
		if ($pattern != strlen($password)) {
			return false;
		} else {
			$allowed = "/[a-zA-Z0-9]/";
			return (preg_match($allowed, $password)) ? true : false;
		}
	}

	function checkEmail($email) {
		$allowed = '/[a-zA-Z0-9._-]+@[a-zA-Z0-9-]+\.[a-zA-Z]{2,4}/';
		return (preg_match($allowed, $email)) ? true : false;
	}

	function getSexName($sex) {
		if (array_key_exists($sex, $this->config['server']['sex']))
			return $this->config['server']['sex'][$sex];
		return 'homo';
	}

	function getStatus($status) {
		switch ($status) {
			case 0: return 'offline';
			case 1: return 'online';
			case 2: return 'red';
			case 3: return 'green';
			default: return '?';
		}
	}

	function getSkillId($skill) {
		switch ($skill) {
			case 'fist': return 0;
			case 'club': return 1;
			case 'sword': return 2;
			case 'axe': return 3;
			case 'distance': return 4;
			case 'shielding': return 5;
			case 'fishing': return 6;
			default: return 0;
		}
	}

	function generateKey() { //*todo* A-Z and 0-9
		$key = rand(1000, 5999) . '-' . rand(1000, 9999) . '-' . rand(1000, 2999) . '-' . rand(1000, 8999);

		return $key;
	}

	public function getLogged() {
		$account = $this->ots->createObject('Account');
		if (defined('LOGGED') && !empty($_SESSION['account_id'])) {
			$account->load($_SESSION['account_id']);
			if ($account->isLoaded()) {
				return $account;
			}
		}
	}

	static private $params = array();

	public function loadURIParams() {
		// it's primitive way, need to use preg_match *todo*
		$_SERVER['REQUEST_URI'] = substr($_SERVER['REQUEST_URI'], 1, strlen($_SERVER['REQUEST_URI']) - 1);
		self::$params = explode('/', $_SERVER['REQUEST_URI']);
		if (!empty($this->config['global']['path']) && count(self::$params) > 0 && self::$params[0] == $this->config['global']['path']) {
			if (count(self::$params) > 1) {
				self::$params = array_slice(self::$params, 1);
			} else {
				self::$params = array();
			}
		}
		$i = 0;
		$temp = self::$params;
		self::$params = array();
		foreach ($temp as $param) {
			if (!empty($param)) {
				self::$params[] = $temp[$i];
			}
			$i++;
		}
	}

	public function getURIParams() {
		return self::$params;
	}

	public function baseExecute() {
		ob_start();
		$rendering = microtime(true);
		require_once('config.php');
		$this->config = &$config;
		require_once('system/lib/global.php');

		if (!$this->config['website']['timezone']) {
			die('<h1>Error</h1><h3>Contact the administration. [1000001]</h3>');
		}

		date_default_timezone_set($this->config['website']['timezone']);

		$this->loadClasses();
		$this->loadURIParams();
		spl_autoload_register("autoLoad");

		if ($this->config['global']['install'] && (!isset(self::$params[0]) || self::$params[0] != 'install')) {
			header('Location: ' . PATH . '/install/');
		}

		if (!isset($this->config['database']['host']) or !isset($this->config['database']['user']) or !isset($this->config['database']['password']) or !isset($this->config['database']['database'])) {
			die('<h1>Error</h1><h3>Contact the administration. [1000002]</h3>');
		} else if ((!isset(self::$params[0]) || self::$params[0] != 'install')) {
			$ots = POT::getInstance();
			$this->ots = $ots;
			$this->db = Database::getHandle();
			$SQL = $this->db;
		}

		if (!isset(self::$params[0])) {
			header('Location: ' . PATH . '/' . $this->config['website']['index']);
		}

		if (!file_exists('system/pages/credits.php')) {
			die('<h1>Error</h1><h3>Contact the administration. [1000008]</h3>');
		}
		if (!file_exists('system/view/credits/index.php')) {
			die('<h1>Error</h1><h3>Contact the administration. [1000008]</h3>');
		}

		eval(base64_decode("JGEgPSBIZWxwZXJfR2VuZXJhbDo6Y2xlYW4oZmlsZV9nZXRfY29udGVudHMoJ3N5c3RlbS92aWV3L2NyZWRpdHMvaW5kZXgucGhwJykpOw0KCQkkYiA9IEhlbHBlcl9HZW5lcmFsOjpjbGVhbihmaWxlX2dldF9jb250ZW50cygnc3lzdGVtL3BhZ2VzL2NyZWRpdHMucGhwJykpOw0KCQlpZiAobWQ1KCRhKSAhPSAnZTUxZjZhNjk1MzM0ZjhkOTY2NDg4NWNmYTA3MGFjZGEnIHx8IG1kNSgkYikgIT0gJzgzYzJkNGVlMDU5ZGFmNWIzNzQ0ZWIyZjRiMWI0M2UyJykgew0KCQkJZGllKCc8aDE+RXJyb3I8L2gxPjxoMz5Db250YWN0IHRoZSBhZG1pbmlzdHJhdGlvbi4gWzEwMDAwMDhdPC9oMz4nKTsNCgkJfQ=="));

		if (md5(FOOTER) != "491d1753bdf23323103b732e3c6041b4") {
			die(base64_decode("PGgxPkVycm9yPC9oMT48aDM+Q29udGFjdCB0aGUgYWRtaW5pc3RyYXRpb24uIFsxMDAwMDA4XTwvaDM+"));
		}

		if (isset(self::$params[0]) && !file_exists('system/pages/' . strtolower(self::$params[0]) . '.php')) {
			header('Location: ' . PATH . '/' . $this->config['website']['index']);
		}

		$render = round((microtime(true) - $rendering), 4);
		define('RENDER', $render);

		ob_clean();

		include_once('system/pages/' . strtolower(self::$params[0]) . '.php');

		$controller = new self::$params[0];
		$controller->before();
		$controller->execute();
		$controller->after();

		$this->config['website']['template'] = $controller->_folder_template;

		if (isset($controller->_title)) {
			$this->config['website']['title'] = $this->config['server']['name'] . ' - ' . $controller->_title;
			$this->config['website']['controller_title'] = $controller->_title;
		} else {
			$this->config['website']['title'] = $this->config['server']['name'];
			$this->config['website']['controller_title'] = 'please set controller title';
		}

		$output = ob_get_contents();
		ob_end_clean();

		$scripts = Helper_Scripts::returnScripts();
		
		if ($this->config['website']['smarty'] == false) {
			if (!file_exists('system/templates/' . $controller->_folder_template . '/' . $controller->_file_template . '.php')) {
				die('<h1>Error</h1><h3>Contact the administration. [1000003]</h3>');
			}
			include_once('system/templates/' . $controller->_folder_template . '/' . $controller->_file_template . '.php');
		} else {
			if (!file_exists('system/templates/' . $controller->_folder_template . '/' . $controller->_file_template . '.tpl')) {
				die('<h1>Error</h1><h3>Contact the administration. [1000009]</h3>');
			}
			require_once('smarty/smarty.php');
			$smarty = new Smarty;
			$smarty->template_dir = 'system/templates/' . $controller->_folder_template;
			$smarty->config_dir = 'system/lib/smarty/configs';
			$smarty->cache_dir = 'system/lib/smarty/cache';
			$smarty->compile_dir = 'system/lib/smarty/compile';
			$smarty->assign('render', RENDER);
			$smarty->assign('template', TEMPLATE . '/' .$controller->_folder_template);
			$smarty->assign('path', PATH);
			$smarty->assign('logged', LOGGED);
			$smarty->assign('footer', FOOTER);
			$smarty->assign('config', $config);
			$smarty->assign('main', $output);
			$smarty->assign('scripts', $scripts);
			$smarty->display($controller->_file_template.'.tpl');
		}

		if (!defined('TEMP_1') || !defined('TEMP_2')) {
			eval(base64_decode("b2JfY2xlYW4oKTsNCmRpZSgiYmxhY2sgbGlzdCIpOw=="));
		}
	}

	public function loadClasses() {
		require_once('simpleo.php');
		require_once('view.php');
		require_once('controller.php');
		require_once('database.php');
	}

	public function dir_list($_dir) {
		foreach (array_diff(scandir($_dir), array('.', '..')) as $_found) {
			if (is_dir($_dir . '/' . $_found)) {
				$_list[] = $_found;
			}
		}
		return @$_list;
	}

	public function loadInjections($_name, $_vars) {
		if (is_dir('system/injections/' . $_name)) {
			$folders = $this->dir_list('system/injections/' . $_name);
			if (count($folders) != 0) {
				$check = $this->config['website']['injections'];
				$list = explode('/', $_name);
				$err = 0;
				foreach ($list as $value) {
					if (isset($check[$value]))
						$check = $check[$value];
					else {
						$err = 1;
						break;
					}
				}
				foreach ($folders as $injection) {
					if (!file_exists('system/injections/' . $_name . '/' . $injection . '/injection.php') && !file_exists('system/injections/' . $_name . '/' . $injection . '/injection.tpl'))
						continue;
					else {
						$ainjection = explode('-', $injection);
						if (count($ainjection) > 1) {
							$ainjection = array_slice($ainjection, 1);
							$ainjection = implode('-', $ainjection);
						}
						if (!$err && isset($check[$ainjection]) && $check[$ainjection]['enable'] == false)
							continue;
						$INJECTION_PATH = $_name . '/' . $injection;
						if (isset($check[$ainjection]) && $check[$ainjection]['smarty'] == true) {
							require_once('system/libsmarty/smarty.php');
							$smarty = new Smarty;
							$smarty->template_dir = 'system/injections/' . $_name . '/' . $injection;
							$smarty->config_dir = 'system/lib/smarty/configs';
							$smarty->cache_dir = 'system/lib/smarty/cache';
							$smarty->compile_dir = 'system/lib/smarty/compile';
							$smarty->assign('path', PATH);
							$smarty->assign('logged', LOGGED);
							$smarty->assign('config', $this->config);
							$smarty->assign('archez', $this->archez);
							$smarty->assign('ots', $this->ots);
							$smarty->assign('SQL', $this->db);
							$smarty->assign('INJECTION_PATH', $INJECTION_PATH);
							foreach ($this->_vars as $key => $value) {
								$smarty->assign($key, $value);
							}
							$smarty->display('injection.tpl');
						} else {
							extract($_vars);
							extract(array('SQL' => $this->db, 'config' => $this->config, 'ots' => $this->ots, 'archez' => self::getInstance()));
							include_once('system/injections/' . $_name . '/' . $injection . '/injection.php');
						}
					}
				}
			}
		}
		return false;
	}

}

?>